<script setup>
import { ref, reactive, watch, nextTick, h } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { warnruleApi as MainApi, warnruleById as MainById, warnruleMultiple, sensorApi, roleTree } from '@T2/service/api.ts';
import { useIuserInfoStore, useCurrentWatchStore } from '@T2/store/users.ts';
import DeviceByUnitPosition from '@T2/views/Project/Manage/components/tree/deviceByUnitPosition.vue';
import dayjs from 'dayjs';

const currentWatchStore = useCurrentWatchStore();
const { curProject } = currentWatchStore;
const iuserInfoStore = useIuserInfoStore();
const { getHandleRight } = iuserInfoStore;
const RIGHT = getHandleRight(['384', '385', '386']);

const MainTable = reactive({
  data: [],
  total: 0,
});
const Filter = reactive({
  page: 1,
  pagesize: 30,
  ordering: '-create_time',
  search: '',
  unit: null,
  device: null,
  ruletype: null,
  level: null,
});
watch(() => ({...Filter}), (nv, ov) => {
  if (nv.page === 1 || nv.page !== ov.page) {
    GetMainTable();
  } else {
    Filter.page = 1;
  }
});
const GetMainTable = () => {
  MainApi({
    method: 'get',
    params: {
      ...Filter,
    }
  }).then(res => {
    MainTable.data = res?.results || [];
    MainTable.total = res?.count || 0;
  });
}
const showRuleCol = (item) => {
  /* 2024-10-24 报警规则回退到之前主题1的逻辑，一条报警规则只设置1个rule */
  const rules = JSON.parse(item);
  const [ rule0 ] = rules;
  return rule0.rule + rule0.value;
}

const unitChange = (data, node) => {
  Filter.unit = data.id;
  Filter.device = null;
}
const deviceChange = (data, node) => {
  Filter.unit = data.unit;
  Filter.device = data.id;
}
const unitlistChange = (list) => {
  MainForm.units = list;
}
const devicelistChange = (list) => {
  MainForm.devices = list;
}

/* 新增编辑 */
const MainPopup = reactive({
  visible: false,
  type: '新增',
});
const MainForm = reactive({
  model: {},
  units: [],
  devices: [],
  sensors: [],
  
  datatype: '',
  datatype_obj: null,
  rule_rule: '',
  rule_value: '',
  channel: [],
  
  cascaderProps: { multiple: true, emitPath: false },
  iusersByRole: [],
});
const MainFormRef = ref(null);
const handleMainAdd = async (isAble = false) => {
  if (!isAble) {
    return;
  }
  MainPopup.visible = true;
  MainPopup.type = '新增';
  MainForm.model = {
    unit: Filter.unit,
    device: Filter.device,
  };
  MainForm.rule_rule = '';
  MainForm.rule_value = '';
  MainForm.datatype = '';
  MainForm.datatype_obj = null;
  MainForm.channel = ['issystem', 'isgzh'];
  MainForm.sensors = await getSensorList(Filter.device);
  getRoleTree();
  nextTick(() => {
    setTimeout(() => {
      MainFormRef.value.clearValidate();
    }, 0)
  });
}
const handleMainEdit = async (isAble = false, row) => {
  if (!isAble) {
    return;
  }
  MainPopup.visible = true;
  MainPopup.type = '编辑';
  MainForm.model = {
    id: row.id,
    unit: row.unit,
    device: row.device,
    ruletype: row.ruletype,
    level: row.level,
    sensor: row.sensor,
    users: row.users,
    info: row.info,
  };
  
  MainForm.channel = [];
  ['issystem', 'isgzh', 'shortmessage', 'email', 'voice'].forEach(i => {
    if (row[i]) {
      MainForm.channel.push(i);
    }
  });
  MainForm.sensors = await getSensorList(row.device);
  sensorFormChange(row.sensor);
  const [ list0 ] = JSON.parse(row.rule);
  MainForm.rule_rule = list0?.rule || '';
  MainForm.rule_value = list0?.value || '';
  getRoleTree();
  nextTick(() => {
    MainFormRef.value.clearValidate();
  });
}
const deviceFormChange = async (e) => {
  MainForm.model.sensor = null;
  MainForm.sensors = await getSensorList(e);
}
const getSensorList = (deviceID) => {
  if (!deviceID) {
    return [];
  }
  return new Promise((resolve, reject) => {
    sensorApi({
      method: 'get',
      params: {
        ordering: '-create_time',
        device__unit: Filter.unit,
        device: deviceID,
        warn: true,
      }
    }).then(res => {
      resolve(res?.results || []);
    }).catch(err => {
      reject([]);
    });
  })
}
const sensorFormChange = (e) => {
  MainForm.rule_rule = '';
  MainForm.rule_value = '';
  MainForm.datatype = '';
  MainForm.datatype_obj = null;
  if (!e) {
    return;
  }
  const obj = MainForm.sensors.find(i => i.id === e);
  MainForm.datatype = obj.datatype;
  if (obj.datatype = '状态型') {
    const oldObj = JSON.parse(obj.datatype_json);
    const newObj = {};
    for (const key in oldObj) {
      if (oldObj[key]) {
        newObj[key] = oldObj[key];
      }
    }
    MainForm.datatype_obj = newObj;
  }
}

/* 推送人员 */
const getRoleTree = () => {
  if (MainForm.iusersByRole.length) {
    return;
  }
  if (curProject.admin_user) {
    MainForm.iusersByRole = [
      { value: curProject.admin_user, label: curProject.admin_user_truename, leaf: true },
    ];
  }
  roleTree({
    method: 'get',
    params: {},
  }).then(res => {
    if (!res?.length) {
      return;
    }
    const list = res.filter(i => i.children?.length);
    list.forEach(role => {
      role.value = role.id;
      role.label = role.name;
      role.children?.forEach(iuser => {
        iuser.value = iuser.id;
        iuser.label = iuser.truename;
        iuser.leaf = true;
      });
    });
    MainForm.iusersByRole = MainForm.iusersByRole.concat(list);
  })
}

const handleMainSubmit = () => {
  if (!MainForm.rule_rule || !MainForm.rule_value) {
    ElMessage.error('触发规则未补充完整！');
    return;
  }
  MainFormRef.value.validate((valid) => {
    if (valid) {
      MainPopup.visible = false;
      if (MainPopup.type === '新增') {
        AddMain();
      } else if (MainPopup.type === '编辑') {
        EditMain();
      }
    }
  });
}
const AddMain = () => {
  othersSolve();
  MainApi({
    method: 'post',
    data: {
      ...MainForm.model,
      project: curProject.id,
      status: true,
      push: 0,
      up: false,
    }
  }).then(res => {
    ElMessage.success('新增成功');
    GetMainTable();
  });
}
const othersSolve = () => {
  ['issystem', 'isgzh', 'shortmessage', 'email', 'voice'].forEach(i => {
    MainForm.model[i] = MainForm.channel.includes(i);
  });
  MainForm.model.rule = JSON.stringify([{ rule: MainForm.rule_rule, value: MainForm.rule_value }]);
}
const EditMain = () => {
  othersSolve();
  MainById({
    method: 'patch',
    id: MainForm.model.id,
    data: {
      ...MainForm.model,
    }
  }).then(res => {
    ElMessage.success('编辑成功');
    GetMainTable();
  });
}
const changeOfStatus = (isAble = false, row) => {
  if (!isAble) {
    return;
  }
	return ElMessageBox.confirm(`是否确认${ row.status ? '关闭？关闭' : '开启？开启'}后，该报警规则触发的报警将${ row.status ? '不再' : '继续'}给用户推送消息`, '提示', {
		confirmButtonText: '确定',
		cancelButtonText: '取消',
		type: 'warning',
	}).then(() => {
		MainById({
			method: 'patch',
			id: row.id,
			data: {
				status: !row.status,
			}
		}).then(res => {
			ElMessage.success('操作成功');
			GetMainTable();
		});
	}).catch(() => {
		ElMessage.info('取消切换！');
	})
}
const handleMainDelete = (isAble = false, row) => {
  if (!isAble) {
    return;
  }
  ElMessageBox.confirm('', {
    message: h('div', null,[
      h('p',{ style:'font-size:16px;color: #4C4C4C;font-weight:500;'}, `您是否要删除该条报警规则？`),
    ]),
    type: 'warning',
    confirmButtonText: '确认',
  }).then(() => {
    MainById({
      method: 'delete',
      id: row.id,
    }).then(res => {
      ElMessage.success('删除成功');
      GetMainTable();
    });
  }).catch(() => {
    ElMessage.info('已取消');
  });
}

/* 显示详情 */
const detailRt = reactive({
  visible: false,
  data: null,
  channel: [],
});
const handleMainDetail = (row) => {
  detailRt.visible = true;
  detailRt.data = row;
  detailRt.channel = [];
  ['issystem', 'isgzh', 'shortmessage', 'email', 'voice'].forEach(i => {
    if (row[i]) {
      detailRt.channel.push(i);
    }
  });
}
const levels = { 一: '#32C5FF', 二: '#F7B500', 三: '#FF0000', 四: '#880404' };


/* 批量操作 */
const mulRt = reactive({
  selData: [],
});
const selectionChange = (selected) => {
  mulRt.selData = selected;
}
const StatusMainMulTable = (isAble = false, flag) => {
  if (!isAble) {
    return;
  }
  let ids = mulRt.selData.map(i => i.id);
  ElMessageBox.confirm('', {
    message: h('div', null,[
      h('p',{ style:'font-size:16px;color: #4C4C4C;font-weight:500;'}, `确定${ flag ? '开启' : '关闭' }勾选的所有报警吗？`),
      h('p',{ style:'font-size:14px;color: #9D9D9D;margin:10px 0;' },`${ flag ? '开启' : '关闭' }后将${ flag ? '继续推送' : '不再接收' }这些报警的推送消息。`),
    ]),
    type: 'warning',
    confirmButtonText: '确认',
  }).then(() => {
    warnruleMultiple({
      method: 'put',
      data: {
        ids,
        update_fileds: {
          status: flag,
        },
      }
    }).then(res => {
      ElMessage.success(`批量${ flag ? '开启' : '关闭' }成功！`);
      GetMainTable();
    });
  }).catch(() => {
    ElMessage.info('已取消');
  });
}
const DeleteMainMulTable = (isAble = false) => {
  if (!isAble) {
    return;
  }
  let ids = mulRt.selData.map(i => i.id);
  ElMessageBox.confirm('', {
    message: h('div', null,[
      h('p',{ style:'font-size:16px;color: #4C4C4C;font-weight:500;'}, `确定批量删除勾选的所有报警吗？`),
      h('p',{ style:'font-size:14px;color: #9D9D9D;margin:10px 0;' },`删除后不可恢复，如有需要请重新新增。`),
    ]),
    type: 'warning',
    confirmButtonText: '确认',
  }).then(() => {
    warnruleMultiple({
      method: 'delete',
      data: {
        ids,
      }
    }).then(res => {
      ElMessage.success(`批量删除成功！`);
      GetMainTable();
    });
  }).catch(() => {
    ElMessage.info('已取消');
  });
}
</script>

<template>
  <div class="view flex">
    <div class="deviceByUnit flex-column">
      <DeviceByUnitPosition
        @unit-change="unitChange"
        @device-change="deviceChange"
        @unitlist-change="unitlistChange"
        @devicelist-change="devicelistChange"
      />
    </div>
    <div class="warnrule-box">
      <div class="flex-column mainCard">
        <el-form label-width="120px" class="flex t_form">
          <el-form-item label="报警类型：">
            <el-select v-model="Filter.ruletype" clearable>
              <el-option value="设备故障" label="设备故障"></el-option>
              <el-option value="工艺异常" label="工艺异常"></el-option>
              <el-option value="系统故障" label="系统故障"></el-option>
              <el-option value="通信故障" label="通信故障"></el-option>
              <el-option value="其他故障" label="其他故障"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="报警等级：">
            <el-select v-model="Filter.level" clearable>
              <el-option value="一" label="一级"></el-option>
              <el-option value="二" label="二级"></el-option>
              <el-option value="三" label="三级"></el-option>
              <el-option value="四" label="四级"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="名称查询：">
            <el-input v-model="Filter.search" clearable></el-input>
          </el-form-item>
          <div class="flex r_btn" style="gap: 10px;margin-bottom: 18px;" v-if="Filter.unit">
            <el-button type="primary" plain @click="StatusMainMulTable(RIGHT['385'], false)" :disabled="!RIGHT['385'] || !mulRt.selData.length">
              批量关闭
            </el-button>
            <el-button type="primary" plain @click="StatusMainMulTable(RIGHT['385'], true)" :disabled="!RIGHT['385'] || !mulRt.selData.length">
              批量开启
            </el-button>
            <el-button type="primary" plain @click="DeleteMainMulTable(RIGHT['386'])" :disabled="!RIGHT['386'] || !mulRt.selData.length">
              批量删除
            </el-button>
            <el-button type="primary" @click="handleMainAdd(RIGHT['384'])" :disabled="!RIGHT['384']">
              新增规则
            </el-button>
          </div>
        </el-form>
        <el-table :data="MainTable.data" scrollbar-always-on @selection-change="selectionChange">
          <el-table-column type="selection" fixed="left" width="55" />
          <el-table-column label="所属站点" prop="unit_name" min-width="160px" fixed="left" show-overflow-tooltip v-if="!Filter.unit"></el-table-column>
          <el-table-column label="所属设备" prop="device_name" min-width="180px" fixed="left" show-overflow-tooltip v-if="!Filter.device"></el-table-column>
          <el-table-column label="报警类型" prop="ruletype" min-width="100px"></el-table-column>
          <el-table-column label="触发规则" prop="rule" min-width="100px">
            <template #default="scope">
              {{ showRuleCol(scope.row.rule) }}
            </template>
          </el-table-column>
          <el-table-column label="报警等级" prop="level" min-width="100px">
            <template #default="scope">
              {{ scope.row.level }}级
            </template>
          </el-table-column>
          <el-table-column label="报警信息" prop="info" min-width="200px"></el-table-column>
          <el-table-column label="报警推送" prop="status" min-width="100px">
            <template #default="scope">
            	<el-switch
                v-model="scope.row.status"
                class="ml-2"
                :before-change="() => { return changeOfStatus(RIGHT['385'], scope.row) }"
                :disabled="!RIGHT['385']"
              />
            </template>
          </el-table-column>
          <el-table-column label="操作" fixed="right" min-width="160px">
            <template #default="scope">
              <el-button link type="primary" @click="handleMainDetail(scope.row)">
                详情
              </el-button>
              <el-button link type="primary" @click="handleMainEdit(RIGHT['385'], scope.row)" :disabled="!RIGHT['385']">
                编辑
              </el-button>
              <el-button link type="danger" @click="handleMainDelete(RIGHT['386'], scope.row)" :disabled="!RIGHT['386']">
                删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>
        <el-pagination
          layout="->, total, prev, pager, next, sizes"
          background
          :page-sizes="[10, 20, 30, 50, 100]"
          :pager-count="5"
          v-model:currentPage="Filter.page"
          v-model:page-size="Filter.pagesize"
          :total="MainTable.total"
        />
      </div>
    </div>
  </div>
  
  <!-- 新增编辑 -->
  <el-dialog width="750px" :title="MainPopup.type + '报警规则'" v-model="MainPopup.visible">
    <el-form
      ref="MainFormRef"
      :model="MainForm.model"
      label-width="120px"
      class="flex flex-wrap"
    >
      <div class="flex flex-wrap" style="width: 100%;">
        <el-form-item style="width: 50%;" prop="device" label="所属站点：">
          <el-select v-model="MainForm.model.unit" disabled>
            <el-option
              v-for="item in MainForm.units"
              :key="item.id"
              :value="item.id"
              :label="item.name"
            />
          </el-select>
        </el-form-item>
        <el-form-item style="width: 50%;" prop="device" label="所属设备：" :rules="[{required: true, message: '不能为空', trigger: 'change'},]">
          <el-select
            v-model="MainForm.model.device"
            @change="deviceFormChange"
            :disabled="Filter.device ? true : false"
            filterable
            clearable
          >
            <el-option
              v-for="item in MainForm.devices"
              :key="item.id"
              :value="item.id"
              :label="item.name"
            />
          </el-select>
        </el-form-item>
        <el-form-item style="width: 50%;" prop="ruletype" label="报警类型：" :rules="[{required: true, message: '不能为空', trigger: 'change'},]">
          <el-select v-model="MainForm.model.ruletype">
            <el-option value="设备故障" label="设备故障"></el-option>
            <el-option value="工艺异常" label="工艺异常"></el-option>
            <el-option value="系统故障" label="系统故障"></el-option>
            <el-option value="通信故障" label="通信故障"></el-option>
            <el-option value="其他故障" label="其他故障"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item style="width: 50%;" prop="level" label="报警等级：" :rules="[{required: true, message: '不能为空', trigger: 'change'},]">
          <el-select v-model="MainForm.model.level">
            <el-option value="一" label="一级"></el-option>
            <el-option value="二" label="二级"></el-option>
            <el-option value="三" label="三级"></el-option>
            <el-option value="四" label="四级"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item style="width: 50%;" prop="sensor" label="变量名称：" :rules="[{required: true, message: '不能为空', trigger: 'change'},]">
          <el-select v-model="MainForm.model.sensor" @change="sensorFormChange" filterable clearable>
            <el-option
              v-for="item in MainForm.sensors"
              :key="item.id"
              :value="item.id"
              :label="item.name"
            />
          </el-select>
        </el-form-item>
        <el-form-item style="width: 50%;" prop="sensor" label="触发规则：" :rules="[{required: true, message: '不能为空', trigger: 'change'},]">
          <div class="flex" style="width: 90%;gap: 10px;" v-if="MainForm.model.sensor">
            <el-select style="width: 50%;" placeholder="条件" v-model="MainForm.rule_rule">
              <template v-if="MainForm.datatype === '数值型'">
                <el-option value=">=" label="大于等于 (>=)"></el-option>
                <el-option value=">" label="大于 (>)"></el-option>
                <el-option value="<=" label="小于等于 (<=)"></el-option>
                <el-option value="<" label="小于 (<)"></el-option>
              </template>
              <el-option value="==" label="等于 (==)"></el-option>
              <el-option value="!=" label="不等于 (!=)"></el-option>
            </el-select>
            <el-input
              v-if="MainForm.datatype === '数值型'"
              style="width: 50%;"
              v-model="MainForm.rule_value"
              placeholder="参考值"
            />
            <el-select v-model="MainForm.rule_value" style="width: 50%;" placeholder="参考值" v-else>
              <el-option
                v-for="(key, index) in MainForm.datatype_obj"
                :key="index"
                :value="key"
                :label="key"
              />
            </el-select>
          </div>
          <p style="color: #c5c5c5" v-else>请先选择变量！</p>
        </el-form-item>
        <el-form-item style="width: 100%;" prop="info" label="报警信息：" :rules="[{required: true, message: '不能为空', trigger: 'blur'},]">
          <el-input style="width: calc(50%*1.9 + 120px*0.05);" v-model="MainForm.model.info" />
        </el-form-item>
        <el-form-item style="width: 100%;" prop="users" label="推送人员：">
          <el-cascader
            style="width: calc(50%*1.9 + 120px*0.05);"
            v-model="MainForm.model.users"
            :options="MainForm.iusersByRole"
            :props="MainForm.cascaderProps"
            :show-all-levels="false"
            collapse-tags
            collapse-tags-tooltip
            :max-collapse-tags="4"
            clearable
          />
        </el-form-item>
        <el-form-item style="width: 100%;" prop="_channel" label="通知渠道：">
          <el-checkbox-group v-model="MainForm.channel">
            <el-checkbox label="系统提示" value="issystem" :disabled="MainPopup.type === '新增' || MainForm.channel.includes('issystem')"></el-checkbox>
            <el-checkbox label="公众号" value="isgzh"></el-checkbox>
            <el-checkbox label="短信" value="shortmessage" disabled></el-checkbox>
            <el-checkbox label="邮件" value="email" disabled></el-checkbox>
            <el-checkbox label="语音" value="voice" disabled></el-checkbox>
          </el-checkbox-group>
        </el-form-item>
      </div>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="MainPopup.visible = false">取 消</el-button>
        <el-button type="primary" @click="handleMainSubmit()">确 定</el-button>
      </span>
    </template>
  </el-dialog>
  
  <el-dialog width="620px" title="规则详情" v-model="detailRt.visible">
    <div class="detail">
      <div class="detail-item flex--center">
        <label>所属站点：</label>
        <p>{{ detailRt.data.unit_name }}</p>
      </div>
      <div class="detail-item flex--center">
        <label>所属设备：</label>
        <p>{{ detailRt.data.device_name }}</p>
      </div>
      <div class="detail-item flex--center">
        <label>报警类型：</label>
        <p>{{ detailRt.data.ruletype }}</p>
      </div>
      <div class="detail-item flex--center">
        <label>报警等级：</label>
        <p :style="{color: levels[detailRt.data.level]}">{{ detailRt.data.level }}级</p>
      </div>
      <div class="detail-item flex--center">
        <label>变量名称：</label>
        <p>{{ detailRt.data.sensor_name }}</p>
      </div>
      <div class="detail-item flex--center">
        <label>触发规则：</label>
        <p>{{ showRuleCol(detailRt.data.rule) }}</p>
      </div>
      <div class="detail-item span2 flex--center">
        <label>报警信息：</label>
        <p>{{ detailRt.data.info }}</p>
      </div>
      <div class="detail-item span2 flex--center">
        <label>推送人员：</label>
        <p>{{ detailRt.data.users_json?.map(i => i.truename)?.join(',') }}</p>
      </div>
      <div class="detail-item span2 flex--center">
        <label>通知渠道：</label>
        <el-checkbox-group v-model="detailRt.channel">
          <el-checkbox label="系统提示" value="issystem" disabled></el-checkbox>
          <el-checkbox label="公众号" value="isgzh" disabled></el-checkbox>
          <!-- <el-checkbox label="短信" value="shortmessage" disabled></el-checkbox>
          <el-checkbox label="邮件" value="email" disabled></el-checkbox>
          <el-checkbox label="语音" value="voice" disabled></el-checkbox> -->
        </el-checkbox-group>
      </div>
      
    </div>
    <template #footer>
      <span class="dialog-footer">
        <el-button type="primary" @click="detailRt.visible = false">关 闭</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
@use '@T2/styles/normal.scss';
.view {
  width: 100%;
  height: 100%;
}
.warnrule-box {
  flex: 1;
  overflow: hidden;
  position: relative;
}
.deviceByUnit {
  width: fit-content;
  height: calc(100% - 20px);
  background: #FFFFFF;
  box-shadow: 0px 0px 2px 0px rgba(0,0,0,0.15);
  border-radius: 10px;
  margin: 10px;
}
.detail {
  padding: 16px 0;
  display: grid;
  gap: 8px;
  grid-template-columns: 1fr 1fr;
  label {
    font-size: 14px;
    color: #999999;
  }
  p {
    font-size: 14px;
    color: #111111;
  }
  .span2 {
    grid-column: span 2;
  }
}
</style>